<?php

m2import('phpinchains/psp/Tag.php');
m2import('phpinchains/tagsupport/URL.php');

/**
 * This paginator is based on code from http://www.strangerstudios.com.
 *
 */
class xt_diggstylepaginatorHandler extends phpinchains_psp_Tag {

/**
 * Is a body tag (if false, body is ignored)
 */
    var $tagType = PSP_EMPTY_TAG;
    /**
     * Tag name in form namespace:tagname
     */
    var $tagName   = 'xt:diggstylepaginator';
    var $requiredAttributes = array(
    'name' => '[\w\d_]+',
    'perPage' => '\d+',
    'length' => '\d+'
    );
    var $attributes = array(
    'name',
    'perPage',
    'numResults',
    'length',
    'action'
    );
    var $env;
    var $params = null;

    function getUrl($page) {
        $url = new phpinchains_tagsupport_URL($this->env);
        $url->setAction($this->getAttribute('action'));
        $url->addParam($this->getAttribute('name'), $page);
        if ($this->getAttribute('medium'))
            $url->setMedium($this->getAttribute('medium'));
        if (is_array($this->params)) {
            foreach ($this->params as $n => $v) {
                $url->addParam($n, $v);
            }
        }
        return $url->toString();
    }

    // based on code from http://www.strangerstudios.com
    //function to return the pagination string
    function getPaginationString($page = 1, $totalitems, $limit = 15, $adjacents = 1, $onestartend = true) {
    //defaults
        if(!$adjacents) $adjacents = 1;
        if(!$limit) $limit = 15;
        if(!$page) $page = 1;

        //other vars
        $prev = $page - 1;									//previous page is page - 1
        $next = $page + 1;									//next page is page + 1
        $lastpage = ceil($totalitems / $limit);				//lastpage is = total items / items per page, rounded up.
        $lpm1 = $lastpage - 1;								//last page minus 1

        $numSelectors = $onestartend?5:7;
        

		/* 
			Now we apply our rules and draw the pagination object. 
			We're actually saving the code to a variable in case we want to draw it more than once.
		*/
        $pagination = "";
        if($lastpage > 1) {
            $pagination .= "<div class=\"pagination\"";
            if($margin || $padding) {
                $pagination .= " style=\"";
                if($margin)
                    $pagination .= "margin: $margin;";
                if($padding)
                    $pagination .= "padding: $padding;";
                $pagination .= "\"";
            }
            $pagination .= ">";
            //previous button
            if ($page > 1)
                $pagination .= "<a href=\"".$this->getUrl($prev)."\">&#171; prev</a>";
            else
                $pagination .= "<span class=\"disabled\">&#171; prev</span>";

            //pages
            if ($lastpage < $numSelectors + ($adjacents * 2))	//not enough pages to bother breaking it up
            {
                for ($counter = 1; $counter <= $lastpage; $counter++) {
                    if ($counter == $page)
                        $pagination .= "<span class=\"current\">$counter</span>";
                    else
                        $pagination .= "<a href=\"".$this->getUrl($counter)."\">$counter</a>";
                }
            }
            elseif($lastpage >= $numSelectors + ($adjacents * 2))	//enough pages to hide some
            {
            //close to beginning; only hide later pages
                if($page < 1 + ($adjacents * 3)) {
                    for ($counter = 1; $counter < 4 + ($adjacents * 2); $counter++) {
                        if ($counter == $page)
                            $pagination .= "<span class=\"current\">$counter</span>";
                        else
                            $pagination .= "<a href=\"".$this->getUrl($counter)."\">$counter</a>";
                    }
                    $pagination .= "...";
                    if (!$onestartend) $pagination .= "<a href=\"".$this->getUrl($lpm1)."\">$lpm1</a>";
                    $pagination .= "<a href=\"".$this->getUrl($lastpage)."\">$lastpage</a>";
                }
                //in middle; hide some front and some back
                elseif($lastpage - ($adjacents * 2) > $page && $page > ($adjacents * 2)) {
                    $pagination .= "<a href=\"".$this->getUrl(1)."\">1</a>";
                    if (!$onestartend) $pagination .= "<a href=\"".$this->getUrl(2)."\">2</a>";
                    $pagination .= "...";
                    for ($counter = $page - $adjacents; $counter <= $page + $adjacents; $counter++) {
                        if ($counter == $page)
                            $pagination .= "<span class=\"current\">$counter</span>";
                        else
                            $pagination .= "<a href=\"".$this->getUrl($counter)."\">$counter</a>";
                    }
                    $pagination .= "...";
                    if (!$onestartend) $pagination .= "<a href=\"".$this->getUrl($lpm1)."\">$lpm1</a>";
                    $pagination .= "<a href=\"".$this->getUrl($lastpage)."\">$lastpage</a>";
                }
                //close to end; only hide early pages
                else {
                    $pagination .= "<a href=\"".$this->getUrl(1)."\">1</a>";
                    if (!$onestartend) $pagination .= "<a href=\"".$this->getUrl(2)."\">2</a>";
                    $pagination .= "...";
                    for ($counter = $lastpage - (1 + ($adjacents * 3)); $counter <= $lastpage; $counter++) {
                        if ($counter == $page)
                            $pagination .= "<span class=\"current\">$counter</span>";
                        else
                            $pagination .= "<a href=\"".$this->getUrl($counter)."\">$counter</a>";
                    }
                }
            }

            //next button
            if ($page < $counter - 1)
                $pagination .= "<a href=\"".$this->getUrl($next)."\">next &#187;</a>";
            else
                $pagination .= "<span class=\"disabled\">next &#187;</span>";
            $pagination .= "</div>\n";
        }
        return $pagination;
    }

    function param($name) {
        return $this->actionform->get($name) ? $this->actionform->get($name) : $this->env->param($name);
    }

    function doStartTag() {
        $this->actionform->gar('__paginatorparams');
        if (!$this->getAttribute('perPage')) return PSP_SKIP_BODY;
        return PSP_EVAL_BODY_BUFFERED;
    }

    function doEndTag() {
        if ($params = $this->actionform->gar('__paginatorparams')) {
            $this->params = $params;
        }
        $ctx = & phpinchains_ApplicationContext::getInstance();
        $this->env = & $ctx->getEnv();
        $name = $this->getAttribute('name');
        $perPage = (int) $this->getAttribute('perPage');
        $length  = (int) $this->getAttribute('length');
        $componentValue = $this->actionform->get($name) ? $this->actionform->get($name) : $this->env->param($name);
        if ($length % 2 == 0)
            $length++;
        $str = $this->getPaginationString($componentValue, (int) $this->getAttribute('numResults'), $perPage, (($length - 1) / 2));
        $this->out->write($str);
        return PSP_SKIP_BODY;
    }

}
?>